package com.xxg.renrenshoppingcart.dao;

import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.IndexOptions;
import com.mongodb.client.model.Indexes;
import com.xxg.renrencommon.domain.bean.UserCartInfo;
import com.xxg.renrenshoppingcart.dao.bean.SkuItem;
import com.xxg.renrenshoppingcart.domain.result.CartProductResult;
import org.bson.Document;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import java.util.*;
import java.util.stream.Collectors;

import static org.springframework.data.mongodb.core.query.Criteria.where;

/**
 * 用户购物车DAO
 *
 * @author xxg
 * @date 2020/11/13
 */
@Repository
public class UserCartInfoDao {
    private final MongoTemplate mongoTemplate;

    public UserCartInfoDao(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
        createCollection();
    }

    /**
     * 创建collection
     */
    private void createCollection() {
        String collectionName = "userCartInfo";
        MongoCollection<Document> collection;
        if (!mongoTemplate.getCollectionNames().contains(collectionName)) {
            collection = mongoTemplate.createCollection(UserCartInfo.class);
            createIndex(collection);
        }
    }

    /**
     * 创建索引
     *
     * @param collection 数据集
     */
    private void createIndex(MongoCollection<Document> collection) {
        collection.createIndex(Indexes.compoundIndex(Indexes.ascending("userId"), Indexes.ascending("skuId"), Indexes.ascending("spuId")));
    }

    /**
     * 插入新的记录
     *
     * @param userCartInfo 用户购物车信息
     */
    public void insert(UserCartInfo userCartInfo) {
        userCartInfo.setCreateTime(new Date());
        userCartInfo.setUpdateTime(new Date());
        mongoTemplate.insert(userCartInfo);
    }

    /**
     * 根据用户ID查询购物车记录
     *
     * @param userId 用户ID
     * @return 购物车记录
     */
    public List<UserCartInfo> findByUserId(Integer userId) {
        Query query = new Query(where("userId").is(userId));
        return mongoTemplate.find(query, UserCartInfo.class);
    }

    /**
     * 更改指定商品在购物车中数量
     *
     * @param userId   会员ID
     * @param skuId    商品规格索引号
     * @param spuId    商品索引号
     * @param increase 数量的增减值
     */
    public void updateByUserIdSkuId(Integer userId, Integer skuId, Integer spuId, Integer increase) {
        Query query = new Query(where("userId").is(userId));
        Criteria criteria = new Criteria();
        criteria.and("skuId").is(skuId).and("spuId").is(spuId);
        query.addCriteria(where("skuItems").elemMatch(criteria));
        Update update = new Update();
        update.inc("skuItems.$.quantity", increase);
        update.set("updateTime", new Date());
        mongoTemplate.updateFirst(query, update, UserCartInfo.class);
    }

    /**
     * 从购物车中移除指定商品
     *
     * @param userId 会员ID
     * @param spuId  商品
     * @param skuId  商品规格
     */
    public void removeSku(Integer userId, Integer spuId, Integer skuId) {
        Query query = new Query(where("userId").is(userId).and("skuId").is(skuId).and("spuId").is(spuId));
        mongoTemplate.remove(query, UserCartInfo.class);
    }

    /**
     * 添加商品到购物车中
     *
     * @param userId  会员ID
     * @param skuItem 商品信息
     */
    public void pushSkuItem(Integer userId, SkuItem skuItem) {
        Query query = new Query(where("userId").is(userId));
        Update update = new Update();
        update.push("skuItems", skuItem);
        mongoTemplate.updateFirst(query, update, UserCartInfo.class);
    }

    /**
     * 清空购物车
     *
     * @param userId 会员ID
     */
    public void removeByUserId(Integer userId) {
        Query query = new Query(where("userId").is(userId));
        mongoTemplate.remove(query, UserCartInfo.class);
    }

    /**
     * 查询购物车商品列表
     *
     * @param userId 会员ID
     * @return 结果
     */
    public List<CartProductResult> queryProduct(String userId) {
        Aggregation agg = Aggregation.newAggregation(
                Aggregation.match(where("userId").is(userId)),
                Aggregation.lookup("productSku", "skuItems.skuId", "skuId", "skuDetail"));
        AggregationResults<CartProductResult> result = mongoTemplate.aggregate(agg, UserCartInfo.class,
                CartProductResult.class);
        return result.getMappedResults();
    }

    /**
     * 设置购物车商品数量
     *
     * @param userId   会员ID
     * @param skuId    商品ID
     * @param quantity 数量
     */
    public void setByUserIdSkuId(Integer userId, Integer skuId, Integer spuId, Integer quantity) {
        Query query = new Query(where("userId").is(userId).and("skuId").is(skuId).and("spuId").is(spuId));
        Update update = new Update();
        update.set("quantity", quantity);
        update.set("updateTime", new Date());
        mongoTemplate.updateFirst(query, update, UserCartInfo.class);
    }

    public void save(UserCartInfo userCartInfo) {
        userCartInfo.setUpdateTime(new Date());
        mongoTemplate.save(userCartInfo);
    }

    public UserCartInfo findByUserIdAndSpuIdAndSkuId(Integer userId, Integer spuId, Integer skuId) {
        Query query = new Query(where("userId").is(userId).and("spuId").is(spuId).and("skuId").is(skuId));
        return mongoTemplate.findOne(query, UserCartInfo.class);
    }
}
